package util;

import java.io.File;
import java.lang.reflect.Field;

import basic.FieldMeta;
import entities.TBrand;
import entities.TWebsite;
import utils.FileUtil;
import utils.StringUtil;

public class TemplateUtil {

	private String tableName;
	private String beanName;
	private String nickName;
	private String headName;
	private String filePath;

	public TemplateUtil(String tableName, String beanName, String nickName, String headName, String filePath) {
		this.tableName = tableName;
		this.beanName = beanName;
		this.nickName = nickName;
		this.headName = headName;
		this.filePath = filePath;
	}

	public <E> void generate(Class<E> target) throws Exception {
		String mapper = generateMapper(target);
		String service = generateService(target);
		String dao = generateDao(target);
		String inter = generateInterface(target);
		File mapperFile = new File(filePath+"mapper//" + "T" + beanName + "Mapper.xml");
		File serviceFile = new File(filePath+"service//"  + beanName + "Service.java");
		File daoFile = new File(filePath+"dao//"  + "I" + beanName + "Dao.java");
		File interFile = new File(filePath+"interface//"  + "I" + beanName + "Service.java");
		FileUtil.write(mapperFile, mapper);
		FileUtil.write(serviceFile, service);
		FileUtil.write(daoFile, dao);
		FileUtil.write(interFile, inter);

	}

	public <E> String generateMapper(Class<E> target) throws Exception {
		Field[] fields = target.getDeclaredFields();
		File file = new File(this.getClass().getResource("/template/mapper.template").getFile());
		String content = FileUtil.read(file);
		content = content.replaceAll("\\[column\\]", getColumn(fields));
		content = content.replaceAll("\\[condition\\]", getCondition(fields));
		content = content.replaceAll("\\[inserta\\]", getInsert(fields)[0]);
		content = content.replaceAll("\\[insertb\\]", getInsert(fields)[1]);
		content = content.replaceAll("\\[update\\]", getUpdate(fields));
		content = content.replaceAll("\\[table_name\\]", tableName);
		content = content.replaceAll("\\[bean_name\\]", beanName);
		content = content.replaceAll("\\[nick_name\\]", nickName);
		return content;
	}

	public <E> String generateService(Class<E> target) throws Exception {
		File file = new File(this.getClass().getResource("/template/service.template").getFile());
		String content = FileUtil.read(file);
		content = content.replaceAll("\\[table_name\\]", tableName);
		content = content.replaceAll("\\[bean_name\\]", beanName);
		content = content.replaceAll("\\[head_name\\]", headName);
		return content;
	}

	public <E> String generateDao(Class<E> target) throws Exception {
		File file = new File(this.getClass().getResource("/template/dao.template").getFile());
		String content = FileUtil.read(file);
		content = content.replaceAll("\\[bean_name\\]", beanName);
		return content;
	}

	public <E> String generateInterface(Class<E> target) throws Exception {
		File file = new File(this.getClass().getResource("/template/interface.template").getFile());
		String content = FileUtil.read(file);
		content = content.replaceAll("\\[bean_name\\]", beanName);
		return content;
	}

	public String getColumn(Field[] fields) {
		StringBuffer sb = new StringBuffer();
		for (Field field : fields) {
			if (field.getName().equals("serialVersionUID")) {
				continue;
			}
			sb.append(nickName + "." + StringUtil.transferUnder(field.getName()) + " , ");
		}
		return StringUtil.removeLast(sb.toString(), ",");
	}

	public String getCondition(Field[] fields) {
		StringBuffer sb = new StringBuffer();
		for (Field field : fields) {
			if (field.getName().equals("serialVersionUID")) {
				continue;
			}
			String name = field.getName();
			String type = field.getGenericType().getTypeName();
			if (type.equals("java.lang.String")) {
				if (field.getAnnotation(FieldMeta.class).primary()) {
					if (field.getAnnotation(FieldMeta.class).range()) {
						sb.append("<if test=\"" + name + " != null and " + name + " != ''\">");
						sb.append(System.lineSeparator());
						sb.append("and ");
						sb.append(System.lineSeparator());
						sb.append("<foreach collection=\"" + name + "\" index=\"index\" item=\"item\" open=\"(\" separator=\"or\" close=\")\">");
						sb.append(System.lineSeparator());
						sb.append(nickName + "." + StringUtil.transferUnder(name) + "  like CONCAT(#{item},'%') ");
						sb.append(System.lineSeparator());
						sb.append("</foreach>");
						sb.append(System.lineSeparator());
						sb.append("</if>");
						sb.append(System.lineSeparator());
					}
				} else if (field.getAnnotation(FieldMeta.class).range()) {
					sb.append("<if test=\"" + name + " != null and " + name + " != ''\">");
					sb.append(System.lineSeparator());
					sb.append("and " + nickName + "." + StringUtil.transferUnder(name) + " in ");
					sb.append(System.lineSeparator());
					sb.append("<foreach collection=\"" + name + "\" index=\"index\" item=\"item\" open=\"(\" separator=\",\" close=\")\">");
					sb.append(System.lineSeparator());
					sb.append("#{item}");
					sb.append(System.lineSeparator());
					sb.append("</foreach>");
					sb.append(System.lineSeparator());
					sb.append("</if>");
					sb.append(System.lineSeparator());
				} else {
					sb.append("<if test=\"" + name + " != null and " + name + " != ''\">");
					sb.append(System.lineSeparator());
					sb.append("and " + nickName + "." + StringUtil.transferUnder(name) + "= #{" + name + "}");
					sb.append(System.lineSeparator());
					sb.append("</if>");
					sb.append(System.lineSeparator());
				}
			}
			if (type.equals("java.lang.Integer")) {
				if (field.getAnnotation(FieldMeta.class).range()) {
					sb.append("<if test=\"" + name + " != null and " + name + " != ''\">");
					sb.append(System.lineSeparator());
					sb.append("and " + nickName + "." + StringUtil.transferUnder(name) + " between ");
					sb.append(System.lineSeparator());
					sb.append("<foreach collection=\"" + name + "\" index=\"index\" item=\"item\" open=\" \" separator=\"and\" close=\" \">");
					sb.append(System.lineSeparator());
					sb.append("#{item}");
					sb.append(System.lineSeparator());
					sb.append("</foreach>");
					sb.append(System.lineSeparator());
					sb.append("</if>");
					sb.append(System.lineSeparator());
				} else {
					sb.append("<if test=\"" + name + " != null \">");
					sb.append(System.lineSeparator());
					sb.append("and " + nickName + "." + StringUtil.transferUnder(name) + "= #{" + name + "}");
					sb.append(System.lineSeparator());
					sb.append("</if>");
					sb.append(System.lineSeparator());
				}
			}
			if (type.equals("java.lang.Double")) {
				if (field.getAnnotation(FieldMeta.class).range()) {
					sb.append("<if test=\"" + name + " != null and " + name + " != ''\">");
					sb.append(System.lineSeparator());
					sb.append("and " + nickName + "." + StringUtil.transferUnder(name) + " between ");
					sb.append(System.lineSeparator());
					sb.append("<foreach collection=\"" + name + "\" index=\"index\" item=\"item\" open=\" \" separator=\"and\" close=\" \">");
					sb.append(System.lineSeparator());
					sb.append("#{item}");
					sb.append(System.lineSeparator());
					sb.append("</foreach>");
					sb.append(System.lineSeparator());
					sb.append("</if>");
					sb.append(System.lineSeparator());
				} else {
					sb.append("<if test=\"" + name + " != null \">");
					sb.append(System.lineSeparator());
					sb.append("and " + nickName + "." + StringUtil.transferUnder(name) + "= #{" + name + "}");
					sb.append(System.lineSeparator());
					sb.append("</if>");
					sb.append(System.lineSeparator());
				}
			}
			if (type.equals("java.util.Date")) {
				if (field.getAnnotation(FieldMeta.class).range()) {
					sb.append("<if test=\"" + name + " != null and " + name + " != ''\">");
					sb.append(System.lineSeparator());
					sb.append("and " + nickName + "." + StringUtil.transferUnder(name) + " between ");
					sb.append(System.lineSeparator());
					sb.append("<foreach collection=\"" + name + "\" index=\"index\" item=\"item\" open=\" \" separator=\"and\" close=\" \">");
					sb.append(System.lineSeparator());
					sb.append("#{item}");
					sb.append(System.lineSeparator());
					sb.append("</foreach>");
					sb.append(System.lineSeparator());
					sb.append("</if>");
					sb.append(System.lineSeparator());
				} else {
					sb.append("<if test=\"" + name + " != null \">");
					sb.append(System.lineSeparator());
					sb.append("and " + nickName + "." + StringUtil.transferUnder(name) + "= #{" + name + "}");
					sb.append(System.lineSeparator());
					sb.append("</if>");
					sb.append(System.lineSeparator());
				}
			}
		}
		return sb.toString();
	}

	public String[] getInsert(Field[] fields) {
		StringBuffer sb1 = new StringBuffer();
		StringBuffer sb2 = new StringBuffer();
		for (Field field : fields) {
			if (field.getName().equals("serialVersionUID")) {
				continue;
			}
			String name = field.getName();
			String type = field.getGenericType().getTypeName();
			if (type.equals("java.lang.String")) {
				sb1.append("<if test=\"" + name + " != null and " + name + " != ''\">");
				sb1.append(System.lineSeparator());
				sb1.append(StringUtil.transferUnder(name) + " , ");
				sb1.append(System.lineSeparator());
				sb1.append("</if>");
				sb1.append(System.lineSeparator());
			}
			if (type.equals("java.lang.Integer")) {
				sb1.append("<if test=\"" + name + " != null \">");
				sb1.append(System.lineSeparator());
				sb1.append(StringUtil.transferUnder(name) + " , ");
				sb1.append(System.lineSeparator());
				sb1.append("</if>");
				sb1.append(System.lineSeparator());
			}
			if (type.equals("java.lang.Double")) {
				sb1.append("<if test=\"" + name + " != null \">");
				sb1.append(System.lineSeparator());
				sb1.append(StringUtil.transferUnder(name) + " , ");
				sb1.append(System.lineSeparator());
				sb1.append("</if>");
				sb1.append(System.lineSeparator());
			}
			if (type.equals("java.util.Date")) {
				sb1.append("<if test=\"" + name + " != null and " + name + " != ''\">");
				sb1.append(System.lineSeparator());
				sb1.append(StringUtil.transferUnder(name) + " , ");
				sb1.append(System.lineSeparator());
				sb1.append("</if>");
				sb1.append(System.lineSeparator());
			}

		}
		for (Field field : fields) {
			if (field.getName().equals("serialVersionUID")) {
				continue;
			}
			String name = field.getName();
			String type = field.getGenericType().getTypeName();
			if (type.equals("java.lang.String")) {
				sb2.append("<if test=\"" + name + " != null and " + name + " != ''\">");
				sb2.append(System.lineSeparator());
				sb2.append("#{" + name + "} , ");
				sb2.append(System.lineSeparator());
				sb2.append("</if>");
				sb2.append(System.lineSeparator());
			}
			if (type.equals("java.lang.Integer")) {
				sb2.append("<if test=\"" + name + " != null \">");
				sb2.append(System.lineSeparator());
				sb2.append("#{" + name + "} , ");
				sb2.append(System.lineSeparator());
				sb2.append("</if>");
				sb2.append(System.lineSeparator());
			}
			if (type.equals("java.lang.Double")) {
				sb2.append("<if test=\"" + name + " != null \">");
				sb2.append(System.lineSeparator());
				sb2.append("#{" + name + "} , ");
				sb2.append(System.lineSeparator());
				sb2.append("</if>");
				sb2.append(System.lineSeparator());
			}
			if (type.equals("java.util.Date")) {
				sb2.append("<if test=\"" + name + " != null and " + name + " != ''\">");
				sb2.append(System.lineSeparator());
				sb2.append("#{" + name + "} , ");
				sb2.append(System.lineSeparator());
				sb2.append("</if>");
				sb2.append(System.lineSeparator());
			}

		}
		return new String[] { sb1.toString(), sb2.toString() };
	}

	public String getUpdate(Field[] fields) {
		StringBuffer sb = new StringBuffer();
		for (Field field : fields) {
			if (field.getName().equals("serialVersionUID")) {
				continue;
			}
			String name = field.getName();
			String type = field.getGenericType().getTypeName();
			if (type.equals("java.lang.String")) {
				if (field.getAnnotation(FieldMeta.class).primary()) {
					
				}else{
					sb.append("<if test=\"" + name + " != null and " + name + " != ''\">");
					sb.append(System.lineSeparator());
					sb.append(StringUtil.transferUnder(name) + " = #{" + name + "} , ");
					sb.append(System.lineSeparator());
					sb.append("</if>");
					sb.append(System.lineSeparator());
				}
			}
			if (type.equals("java.lang.Integer")) {
				sb.append("<if test=\"" + name + " != null \">");
				sb.append(System.lineSeparator());
				sb.append(StringUtil.transferUnder(name) + " = #{" + name + "} , ");
				sb.append(System.lineSeparator());
				sb.append("</if>");
				sb.append(System.lineSeparator());
			}
			if (type.equals("java.lang.Double")) {
				sb.append("<if test=\"" + name + " != null \">");
				sb.append(System.lineSeparator());
				sb.append(StringUtil.transferUnder(name) + " = #{" + name + "} , ");
				sb.append(System.lineSeparator());
				sb.append("</if>");
				sb.append(System.lineSeparator());
			}
			if (type.equals("java.util.Date")) {
				sb.append("<if test=\"" + name + " != null and " + name + " != ''\">");
				sb.append(System.lineSeparator());
				sb.append(StringUtil.transferUnder(name) + " = #{" + name + "} , ");
				sb.append(System.lineSeparator());
				sb.append("</if>");
				sb.append(System.lineSeparator());
			}

		}
		return sb.toString();
	}

	public static void main(String[] args) throws Exception {
		// 生成mapper文件 构造方法包括小写表名 类名 前缀 和文件生成路径
//		new TemplateUtil("bank", "Bank", "bnk", "Bnk", "d://DataBean//").generate(TBank.class);
//		new TemplateUtil("bin", "Bin", "bin", "Bin", "d://DataBean//").generate(TBin.class);
//		new TemplateUtil("blackbin", "Blackbin", "bck", "Bck", "d://DataBean//").generate(TBlackbin.class);
//		new TemplateUtil("blackcard", "Blackcard", "bck", "Bck", "d://DataBean//").generate(TBlackcard.class);
//		new TemplateUtil("blackcountry", "Blackcountry", "bck", "Bck", "d://DataBean//").generate(TBlackcountry.class);
//		new TemplateUtil("blackfinger", "Blackfinger", "bck", "Bck", "d://DataBean//").generate(TBlackfinger.class);
//		new TemplateUtil("blackip", "Blackip", "bck", "Bck", "d://DataBean//").generate(TBlackip.class);
//		new TemplateUtil("blackstate", "Blackstate", "bck", "Bck", "d://DataBean//").generate(TBlackstate.class);
//		new TemplateUtil("blackname", "Blackname", "bck", "Bck", "d://DataBean//").generate(TBlackname.class);
//		new TemplateUtil("blackphone", "Blackphone", "bck", "Bck", "d://DataBean//").generate(TBlackphone.class);
//		new TemplateUtil("blackaddr", "Blackaddr", "bck", "Bck", "d://DataBean//").generate(TBlackaddr.class);
//		new TemplateUtil("blackemail", "Blackemail", "bck", "Bck", "d://DataBean//").generate(TBlackemail.class);
//		new TemplateUtil("blackwebsite", "Blackwebsite", "bck", "Bck", "d://DataBean//").generate(TBlackwebsite.class);
//		new TemplateUtil("card", "Card", "crd", "Crd", "d://DataBean//").generate(TCard.class);
//		new TemplateUtil("currency", "Currency", "cur", "Cur", "d://DataBean//").generate(TCurrency.class);
//		new TemplateUtil("merchant", "Merchant", "mer", "Mer", "d://DataBean//").generate(TMerchant.class);
//		new TemplateUtil("notice", "Notice", "ntc", "Ntc", "d://DataBean//").generate(TNotice.class);
//		new TemplateUtil("subject", "Subject", "sub", "Sub", "d://DataBean//").generate(TSubject.class);
//		new TemplateUtil("transaction", "Transaction", "txn", "Txn", "d://DataBean//").generate(TTransaction.class);
		new TemplateUtil("website", "Website", "web", "Web", "d://DataBean//").generate(TWebsite.class);
//		new TemplateUtil("whitecard", "Whitecard", "wht", "Wht", "d://DataBean//").generate(TWhitecard.class);
//		new TemplateUtil("whiteip", "Whiteip", "wht", "Wht", "d://DataBean//").generate(TWhiteip.class);
//		new TemplateUtil("bc", "Bc", "bc", "Bc", "d://DataBean//").generate(TBc.class);
//		new TemplateUtil("cb", "Cb", "cb", "Cb", "d://DataBean//").generate(TCb.class);
//		new TemplateUtil("sc", "Sc", "sc", "Sc", "d://DataBean//").generate(TSc.class);
//		new TemplateUtil("cs", "Cs", "cs", "Cs", "d://DataBean//").generate(TCs.class);
//		new TemplateUtil("sm", "Sm", "sm", "Sm", "d://DataBean//").generate(TSm.class);
//		new TemplateUtil("ms", "Ms", "ms", "Ms", "d://DataBean//").generate(TMs.class);
//		new TemplateUtil("bm", "Bm", "bm", "Bm", "d://DataBean//").generate(TBm.class);
//		new TemplateUtil("mb", "Mb", "mb", "Mb", "d://DataBean//").generate(TMb.class);
//		new TemplateUtil("catalog", "Catalog", "cat", "Cat", "d://DataBean//").generate(TCatalog.class);
//		new TemplateUtil("function", "Function", "fun", "Fun", "d://DataBean//").generate(TFunction.class);
//		new TemplateUtil("operator", "Operator", "opt", "Opt", "d://DataBean//").generate(TOperator.class);
//		new TemplateUtil("role", "Role", "rol", "Rol", "d://DataBean//").generate(TRole.class);
//		new TemplateUtil("resource", "Resource", "res", "Res", "d://DataBean//").generate(TResource.class);

//		new TemplateUtil("intercept", "Intercept", "inc", "Inc", "d://DataBean//").generate(TIntercept.class);
//		new TemplateUtil("logic", "Logic", "log", "Log", "d://DataBean//").generate(TLogic.class);
//		new TemplateUtil("risk", "Risk", "rsk", "Rsk", "d://DataBean//").generate(TRisk.class);
//		new TemplateUtil("csm", "Csm", "csm", "Csm", "d://DataBean//").generate(TCsm.class);
//		new TemplateUtil("bcb", "Bcb", "bcb", "Bcb", "d://DataBean//").generate(TBcb.class);
//		new TemplateUtil("bmb", "Bmb", "bmb", "Bmb", "d://DataBean//").generate(TBmb.class);
//		new TemplateUtil("csc", "Csc", "csc", "Csc", "d://DataBean//").generate(TCsc.class);
//		new TemplateUtil("msm", "Msm", "msm", "Msm", "d://DataBean//").generate(TMsm.class);
//		new TemplateUtil("scb", "Scb", "scb", "Scb", "d://DataBean//").generate(TScb.class);
//		new TemplateUtil("smb", "Smb", "smb", "Smb", "d://DataBean//").generate(TSmb.class);
//		new TemplateUtil("mail", "Mail", "mal", "Mal", "d://DataBean//").generate(TMail.class);
//		new TemplateUtil("news", "News", "new", "New", "d://DataBean//").generate(TNews.class);
//		new TemplateUtil("bal", "Balance", "bal", "Bal", "d://DataBean//").generate(TBalance.class);
//		new TemplateUtil("settle", "Settle", "ste", "Ste", "d://DataBean//").generate(TSettle.class);
//		new TemplateUtil("link", "Link", "lnk", "Lnk", "d://DataBean//").generate(TLink.class);
//		new TemplateUtil("product", "Product", "pct", "Pct", "d://DataBean//").generate(TProduct.class);
//		new TemplateUtil("replace", "Replace", "rep", "Rep", "d://DataBean//").generate(TReplace.class);
//		new TemplateUtil("ip", "Ips", "ips", "Ips", "d://DataBean//").generate(TIps.class);
//		new TemplateUtil("mcc", "Mcc", "mcc", "Mcc", "d://DataBean//").generate(TMcc.class);
		new TemplateUtil("brand", "Brand", "bnd", "Bnd", "d://DataBean//").generate(TBrand.class);
	}

}
